unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, IniFiles;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    GroupBox1: TGroupBox;
    StatusBar1: TStatusBar;
    GroupBox2: TGroupBox;
    Button1: TButton;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Edit2: TEdit;
    Edit3: TEdit;
    Label3: TLabel;
    ComboBox1: TComboBox;
    Label4: TLabel;
    Timer1: TTimer;
    Edit4: TEdit;
    Label5: TLabel;

    procedure Button1Click(Sender: TObject);
    procedure RadioButton1Click(Sender: TObject);
    procedure RadioButton2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

    function  RunDosCommand(command: String):string;stdcall;

var
  Form1: TForm1;
  hReadPipe: THandle;
  hWritePipe: THandle;
  inifile: Tinifile;
  logfile: String;
  command1 :String;
implementation

{$R *.dfm}

function  RunDosCommand(command: String):string;stdcall;
var
  SI: TStartUpInfo;
  PI: TProcessInformation;
  SA: TSecurityAttributes;
//SD: TSecurityDescriptor;
  BytesRead: DWORD;
  Dest: array[0..1023] of char;
  CmdLine: array[0..512] of char;
  TmpList: TStringList;
  Avail, ExitCode, wrResult: DWORD;
  osVer: TOSVERSIONINFO;
  tmpstr: AnsiString;
begin
  osVer.dwOSVersionInfoSize := Sizeof(TOSVERSIONINFO);
  GetVersionEX(osVer);

  Form1.Memo1.Lines.Append(command1);

  if osVer.dwPlatformId = VER_PLATFORM_WIN32_NT then
  begin
  //InitializeSecurityDescriptor(@SD,   SECURITY_DESCRIPTOR_REVISION);
  //SetSecurityDescriptorDacl(@SD,   True,   nil,   False);
    SA.nLength := SizeOf(SA);
    SA.lpSecurityDescriptor := nil; //@SD;
    SA.bInheritHandle := True;
    CreatePipe(hReadPipe, hWritePipe, @SA, 0);
  end
  else
    CreatePipe(hReadPipe, hWritePipe, nil, 1024);
  try
    FillChar(SI, SizeOf(SI), 0);
    SI.cb := SizeOf(TStartUpInfo);
    SI.wShowWindow := SW_HIDE;
    SI.dwFlags := STARTF_USESHOWWINDOW;
    SI.dwFlags := SI.dwFlags or STARTF_USESTDHANDLES;
    SI.hStdOutput := hWritePipe;
    SI.hStdError := hWritePipe;
    StrPCopy(CmdLine, Command1);
    if CreateProcess(nil, CmdLine, nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then
    begin
      ExitCode := 0;
      while ExitCode = 0 do
      begin
        wrResult := WaitForSingleObject(PI.hProcess, 500);
        if PeekNamedPipe(hReadPipe, @Dest[0], 1024, @Avail, nil, nil) then
        begin
          if Avail > 0 then
          begin
            TmpList := TStringList.Create;
            try
              FillChar(Dest, SizeOf(Dest), 0);
              ReadFile(hReadPipe, Dest[0], Avail, BytesRead, nil);
              TmpStr := Copy(Dest, 0, BytesRead - 1);
              TmpList.Text := TmpStr;
              Form1.Memo1.Lines.Append(tmpstr);
            finally
              TmpList.Free;
            end;
          end;
        end;
        if wrResult <> WAIT_TIMEOUT then ExitCode := 1;
      end;
      GetExitCodeProcess(PI.hProcess, ExitCode);
      CloseHandle(PI.hProcess);
      CloseHandle(PI.hThread);
    end;
  finally
    CloseHandle(hReadPipe);
    CloseHandle(hWritePipe);
  end;
  Form1.Memo1.Lines.Append('Thread exit!');
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
  param: String;
  command: String;
  Tid: Dword;
begin
  winexec('cmd.exe /c taskkill /f /t /im iperf.exe',sw_hide);

  if (RadioButton1.Checked = false) and (RadioButton2.Checked = false)then  begin
    Application.MessageBox('Please select one mode', 'Error', 48);
    exit;
  end;
  
  Sleep(500);

  if RadioButton1.Checked = True then
    param := ' -s -i ' + Edit2.Text + ' -p ' + Edit3.Text + ' -w ' + ComboBox1.Text;

  if RadioButton2.Checked = True then
    param := ' -c ' + Edit1.Text + ' -i ' + Edit2.Text + ' -p ' + Edit3.Text + ' -w ' + ComboBox1.Text + ' -t ' + Edit4.Text;

  inifile:=Tinifile.create('.\setting.ini');
  inifile.WriteString('CONFIG', 'IP', Edit1.Text);
  inifile.WriteString('CONFIG', 'TIMER', Edit2.Text);
  inifile.WriteString('CONFIG', 'PORT', Edit3.Text);
  inifile.WriteString('CONFIG', 'SIZE', ComboBox1.Text);
  inifile.WriteString('CONFIG', 'TIME', Edit4.Text);
  inifile.Free;

  command := 'iperf.exe ' + param;
  command1 := command;
  StatusBar1.Panels[0].Text := 'App is running.....';
  CreateThread(nil, 0, @RunDosCommand, nil, 0, Tid);
  //RunDosCommand(command);
end;

procedure TForm1.RadioButton1Click(Sender: TObject);
begin
  Edit1.Enabled := False;
  Edit4.Enabled := False;
end;

procedure TForm1.RadioButton2Click(Sender: TObject);
begin
  Edit1.Enabled := True;
  Edit4.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Memo1.Lines.SaveToFile('.\'+logfile);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  winexec('cmd.exe /c taskkill /f /t /im iperf.exe',sw_hide);
  StatusBar1.Panels[0].Text := 'App is Stoped.....';
end;

procedure TForm1.FormCreate(Sender: TObject);
Var
  systime: TSYSTEMTIME;
begin
  if not FileExists('.\iperf.exe') then
    Application.MessageBox('iperf.exe not found', 'Error', 48);

  if FileExists('.\setting.ini') then begin
    inifile:=Tinifile.create('.\setting.ini');
    Edit1.Text := inifile.ReadString('CONFIG', 'IP', '192.168.11.3');
    Edit2.Text := inifile.ReadString('CONFIG', 'TIMER', '2');
    Edit3.Text := inifile.ReadString('CONFIG', 'PORT', '4502');
    ComboBox1.Text := inifile.ReadString('CONFIG', 'SIZE', '64k');
    Edit4.Text := inifile.ReadString('CONFIG', 'TIME', '60');
    inifile.Free;
  end;

  GetLocalTime(systime);
  logfile := 'log-'+IntToStr(systime.wYear)+IntToStr(systime.wMonth)+IntToStr(systime.wDay)+IntToStr(systime.wHour)+IntToStr(systime.wMinute)+IntToStr(systime.wSecond)+'.log';
end;

end.
